﻿using Client.Constant;
using Client.Framework.Event;
using Client.Framework.Message;
using Client.Framework.Socket;
using Client.Message.Request;
using Client.Message.Response;
using Client.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client.Service
{
    /// <summary>
    /// Author: Leil
    /// Description: OrgService
    /// CreateTime: 2020/6/3 15:23:04
    /// </summary>
    public class OrgService
    {
        public delegate void RefreshOrgTree(List<ViewOrg> tree);

        public event RefreshOrgTree RefreshOrgTreeEvent;
        public event RefreshOrgTree RefreshRootOrgTreeEvent;


        private static OrgService instance;

        private OrgService()
        {
            MessageEventPublisher.SubscribeEvent(MessageId.RESPONSE_ORG_TREE, ResponseOrgTree);
        }

        public static OrgService Instance()
        {
            if (instance == null)
            {
                instance = new OrgService();
            }
            return instance;
        }

        /// <summary>
        /// 初始化组织树
        /// </summary>
        public void InitOrgTree()
        {
            RequestOrgTree();
        }

        /// <summary>
        /// 组织字典
        /// </summary>
        private Dictionary<int, ViewOrg> OrgDic { get; set; }
        /// <summary>
        /// 带根组织的组织树
        /// </summary>
        public List<ViewOrg> RootOrgTree { get; private set; }
        /// <summary>
        /// 不带根组织的组织树
        /// </summary>
        public List<ViewOrg> OrgTree { get; private set; }

        /// <summary>
        /// 根据ID获取组织
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ViewOrg GetOrgById(int id)
        {
            if (OrgDic.ContainsKey(id))
            {
                return OrgDic[id];
            }
            return null;
        }

        /// <summary>
        /// 获取组织树事件订阅器
        /// </summary>
        /// <param name="refreshEvent"></param>
        public void SubscribeRefreshOrgTreeEvent(RefreshOrgTree refreshEvent)
        {
            RefreshOrgTreeEvent += refreshEvent;
        }

        /// <summary>
        /// 获取带根组织树事件订阅器
        /// </summary>
        /// <param name="refreshEvent"></param>
        public void SubscribeRefreshRootOrgTreeEvent(RefreshOrgTree refreshEvent)
        {
            RefreshRootOrgTreeEvent += refreshEvent;
        }


        /// <summary>
        /// 请求组织机构树
        /// </summary>
        public void RequestOrgTree()
        {
            OrgTreeReq msg = new OrgTreeReq(MessageId.REQUEST_ORG_TREE);
            ApplicationClient.Instance().Send(msg);
        }

        private void ResponseOrgTree(ResponseBaseMessage message)
        {
            if (message is OrgTreeResp msg)
            {
                InitOrgTree(msg.OrgList);
            }
        }


        private void InitOrgTree(List<ViewOrg> orgs)
        {
            OrgDic = orgs.ToDictionary(obj => obj.ID, obj => obj);
            List<ViewOrg> tree = new List<ViewOrg>();
            orgs.ForEach(o =>
            {
                FindAncestor(o, tree);
            });

            OrgTree = tree;
            RefreshOrgTreeEvent?.Invoke(OrgTree);
            AddRoot(tree);
        }

        public void AddRoot(List<ViewOrg> tree)
        {
            ViewOrg viewOrg = new ViewOrg()
            {
                ID = 0,
                OrgName = "根组织",
            };
            viewOrg.SubOrgs.AddRange(tree);
            // 添加根组织
            RootOrgTree = new List<ViewOrg>
            {
                viewOrg
            };
            RefreshRootOrgTreeEvent?.Invoke(RootOrgTree);
        }

        private void FindAncestor(ViewOrg org, List<ViewOrg> tree)
        {
            if (org.ParentId == 0)
            {
                if (tree.Contains(org))
                {
                    return;
                }
                tree.Add(org);
            }
            else
            {
                if (OrgDic.ContainsKey(org.ParentId))
                {
                    ViewOrg parent = OrgDic[org.ParentId];
                    if (!parent.SubOrgs.Contains(org))
                    {
                        parent.SubOrgs.Add(org);
                    }
                    FindAncestor(parent, tree);
                }
            }
        }





    }
}
